package com.huangfu.learning.javabase.java.pattern.create.factorymethod;

/**
 * Created with IntelliJ IDEA.
 * Author: huangfu.daohui
 * Date: 2018/8/2
 * Time: 19:49
 * Version: 1.0
 * Description:工厂方法模式
 * https://blog.csdn.net/carson_ho/article/details/52343584
 * <p>
 * 步骤1： 创建抽象工厂类，定义具体工厂的公共接口；
 * 步骤2： 创建抽象产品类 ，定义具体产品的公共接口；
 * 步骤3： 创建具体产品类（继承抽象产品类） & 定义生产的具体产品；
 * 步骤4：创建具体工厂类（继承抽象工厂类），定义创建对应具体产品实例的方法；
 * 步骤5：外界通过调用具体工厂类的方法，从而创建不同具体产品类的实例
 * <p>
 * 背景：小成有一间塑料加工厂（仅生产A类产品）；随着客户需求的变化，客户需要生产B类产品；
 * 冲突：改变原有塑料加工厂的配置和变化非常困难，假设下一次客户需要再发生变化，再次改变将增大非常大的成本；
 * 解决方案：小成决定置办塑料分厂B来生产B类产品；
 * 即工厂方法模式
 **/
//步骤5：外界通过调用具体工厂类的方法，从而创建不同具体产品类的实例
public class FactoryMethod {
    public static void main(String[] args) {
        //客户要产品A
        Factory mFactoryA = new FactoryA();
        mFactoryA.manufacture().show();

        //客户要产品B
        Factory mFactoryB = new FactoryB();
        mFactoryB.manufacture().show();
    }
}


/**
 * 步骤1： 创建抽象工厂类，定义具体工厂的公共接口；
 */
abstract class Factory{
    abstract Product manufacture();
}

/**
 * 步骤2： 创建抽象产品类 ，定义具体产品的公共接口；
 */
abstract class Product{
    public abstract void show();
}

/**
 * 步骤3： 创建具体产品类（继承抽象产品类） & 定义生产的具体产品；
 */
class ProductA extends Product{

    @Override
    public void show() {
        System.out.println("工厂A 生产出了A产品");
    }
}

/**
 * 步骤3： 创建具体产品类（继承抽象产品类） & 定义生产的具体产品；
 */
class ProductB extends Product{

    @Override
    public void show() {
        System.out.println("工厂B 生产出了B产品");
    }
}


/**
 * 步骤4：创建具体工厂类（继承抽象工厂类），定义创建对应具体产品实例的方法；
 */
class FactoryA extends Factory{

    @Override
    Product manufacture() {
        return new ProductA();
    }
}

/**
 * 步骤4：创建具体工厂类（继承抽象工厂类），定义创建对应具体产品实例的方法；
 */
class FactoryB extends Factory{

    @Override
    Product manufacture() {
        return new ProductB();
    }
}